import random
import os
def get_number_by_pro(number_list,pro_list):
    x = random.uniform(0,1)
    sum_pro =0.0
    for number,number_pro in zip(number_list,pro_list):
        sum_pro+=number_pro
        if x<sum_pro:
            return number

def rc(nx):
    """
    :param nx: circuit input number
    :param na: ISW Xor number
    :return: the circuit
    """
    opts=['and','xor','ref']
    # random.shuffle(opt)
    # print(opt)
    # opt_n=na+nm+nr
    ix=0
    iv=nx
    V=[]
    E=[]
    Y=[]
    while nx>0:
        opt=random.choice(opts)
        if opt=='ref':
            opts.remove('ref')
            rd=random.randint(0,1)
            if rd ==1 and nx>=1:
                left=ix
                V.append(left)
                V.append(iv)
                Y.append(iv)
                E.append([opt,left])
                ix+=1
                iv+=1
                nx-=1 
            elif rd == 0 and len(V)>=1:
                left = random.choice(V)
                if [opt,left] not in E:
                    if left in Y:
                        Y.remove(left)
                    Y.append(iv)
                    E.append([opt,left])
                    iv+=1
            
        elif (opt =='and') or (opt=='xor'):
            rd=get_number_by_pro([0,1,2],[0.8,0.1,0.1])
            if rd==0 and len(V)>=2:
                ops=random.sample(V,2)
                if ([opt,ops[0],ops[1]] not in E) and ([opt,ops[1],ops[0]] not in E):
                    left,right=ops[0],ops[1]
                    if left in Y:
                        Y.remove(left)
                    if right in Y:
                        Y.remove(right)
                    Y.append(iv)
                    E.append([opt,left,right])
                    iv+=1
            elif (rd==1 and len(V)>=1) and nx>=1:
                left = random.choice(V)
                if left in Y:
                    Y.remove(left)
                right = ix
                V.append(left)
                V.append(right)
                V.append(iv)
                Y.append(iv)
                E.append([opt,left,right])
                ix+=1
                iv+=1
                nx-=1
            elif rd==2 and nx>=2:
                left = ix
                right = ix+1
                V.append(left)
                V.append(right)
                E.append([opt,left,right])
                V.append(iv)
                Y.append(iv)
                ix+=2
                iv+=1
                nx-=2
                
        else:
            # raise Exception('Invalid Operation')
            pass
    return E,Y

print('--------------------test---------------------------')
print('            random circuit')
nx=5
path=f'./circuits/input_number_{nx}/'
if not (os.path.exists(path)):
    os.makedirs(path)
for i in range(10000):

    E,Y=rc(nx)
    print(E,Y)

    with open(path+'c'+str(i)+'.txt','w') as f:
        for ii in range(nx):
            f.write('in '+str(ii)+'\n')
        for s in E:
            text = map(str,s)
            t = ' '.join(text)
            f.write(t+'\n')
        for o in Y:
            f.write('out '+str(o)+'\n')
# E=rc(3,0,0,2)
# print(E)
